# -*- coding: utf-8 -*-
import json
import shutil
import sys
import csv
import pandas as pd
import numpy as np
import os
from sqlalchemy import create_engine
from datetime import datetime
import time
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager

# 设置标准输出和标准错误为 UTF-8 编码
sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf-8', buffering=1)
sys.stderr = open(sys.stderr.fileno(), mode='w', encoding='utf-8', buffering=1)

engine = create_engine('mysql+pymysql://root:employment_analysis@47.116.203.76/employment')
file_title = ''

# 获取数据
def get_data(keyword):
    # GitHub大佬SergeyPirogov写了浏览器驱动管理器webdriver-manager，可以使设置驱动变得更加方便。
    service = ChromeService(executable_path=ChromeDriverManager().install())

    # 启动无头浏览器
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=old")
    # options.add_argument("--headless")  # 启用无头模式
    options.add_argument("--disable-gpu")  # 禁用GPU加速
    options.add_argument("--no-sandbox")  # 禁用沙箱
    # options.add_argument("--remote-debugging-port=9222")  # 启用调试端口

    # 启动浏览器
    driver = webdriver.Chrome(service=service, options=options)

    # 打开目标网页
    driver.get("http://localhost:5173/#/script")  # 将网址替换为实际网址

    # 等待页面加载完成
    wait = WebDriverWait(driver, 10)  # 最长等待时间为10秒

    # 使用 XPath 定位元素并输入关键词
    input_keyword = driver.find_element(By.XPATH, "/html/body/div[1]/div/div/section/section/main/div/div/div/input")
    input_keyword.send_keys(keyword)

    # 定位爬取按钮
    crawl_button = wait.until(
        EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div/div/section/section/main/div/button')))
    crawl_button.click()

    time.sleep(1)

    # 初始化爬取计数器
    crawl_count = 1

    # 开始循环点击按钮获取数据 当计数器达到10次则停止（防止逻辑错误导致不断循环）
    while crawl_count < 10:
        # 定位获取数据按钮
        data_button = wait.until(EC.presence_of_element_located(
            (By.XPATH, '/html/body/div[1]/div/div/section/section/main/div[2]/button')))
        data_button.click()

        # 等待新窗口打开
        WebDriverWait(driver, 10).until(EC.new_window_is_opened)

        # 获取所有窗口句柄并切换到新窗口
        window_handles = driver.window_handles
        driver.switch_to.window(window_handles[-1])
        time.sleep(3)

        # 等待新页面加载完成并定位到包含 JSON 数据的元素
        json_element = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.TAG_NAME, 'pre'))
        )

        # 提取 JSON 数据
        json_data = json_element.text

        # 解析 JSON 数据
        json_obj = json.loads(json_data)

        # 判断 totalCount 是否为 0，如果是则退出循环
        total_count = json_obj.get('resultbody', {}).get('job', {}).get('totalCount', 0)
        print(total_count)
        if total_count == 0:
            break

        # 保存 JSON 数据到文件，文件名根据爬取次数递增
        file_name = f'{file_title}script_data/data_{crawl_count}.json'
        with open(file_name, 'w', encoding='utf-8') as f:
            f.write(json.dumps(json_obj, ensure_ascii=False) + '\n')

        print(f"JSON 数据已保存到 {file_name} 文件中")

        # 增加爬取计数器
        crawl_count += 1

        # 关闭当前窗口并切换回主窗口
        driver.close()
        driver.switch_to.window(window_handles[0])

        # 等待 1 秒后继续下一次点击
        time.sleep(1)

    # 关闭浏览器
    driver.quit()


# 提取json数据  运行成功
def parse_job_data(data):
    job_list = data['resultbody']['job']['items']
    parsed_jobs = []

    for job in job_list:
        parsed_job = {
            'job_id': job['jobId'],
            '岗位类型': '全职' if job['jobType'] == '0' else '其他',  # 假设'0'表示全职
            'position': job['jobName'],
            'city': job['jobAreaString'],
            'company': job['companyName'],
            '公司类型': job['companyTypeString'],
            'scale': job['companySizeString'],
            '薪资范围': job['provideSalaryString'],
            'job_create_time': job['confirmDateString'],
            # 'update_time': job['updateDateTime'],
            'job_update_time': job['updateDateTime'],
            'experience': job['workYearString'],
            'education': job['degreeString'],
            'responsibility': job['jobDescribe'],
            'position_link': job['jobHref']
        }
        parsed_jobs.append(parsed_job)

    return parsed_jobs

# 保存数据
def write_to_csv(parsed_data, output_file_name):
    if not parsed_data:
        print(f"No script_data to write for {output_file_name}")
        return
    output_file = str(file_title) + 'temp/' + str(output_file_name) + '.csv'
    headers = list(parsed_data[0].keys())
    with open(output_file, 'w', encoding='utf-8', newline='') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=headers)
        writer.writeheader()
        for row in parsed_data:
            writer.writerow(row)
    # 清洗数据
    wash_data_all(output_file)
    print(output_file)

# 启动解析数据  运行成功
def analysis_json(name):
    for index, i in enumerate(name, start=1):  # 从1开始的索引
        file_name = str(file_title) + 'script_data/' + i
        # 新名字
        new_name = os.path.splitext(i)[0]

        # 判断文件是否为空
        if os.path.getsize(file_name) == 0:
            print(f"File {i} is empty. Skipping...")
            continue

        with open(file_name, 'r', encoding='utf-8') as file:
            data = json.load(file)
            parsed_jobs = parse_job_data(data)
            write_to_csv(parsed_jobs, new_name)

# 保留特定省份的数据
def filter_provinces(df):
    allowed_provinces = ["广东", "广西", "福建", "云南", "贵州", "海南"]
    return df[df['province'].isin(allowed_provinces)]

# 各个数据表统一清洗的操作
def wash_data_all(path):
    # 读取文件
    df = pd.read_csv(path)
    df.reset_index(drop=True, inplace=True)
    # 清洗地点
    df[['地点1', '地区']] = df['city'].str.split('·', expand=True)
    df['city'] = df['地点1']
    # 城市映射关系
    city_to_province = {
        "上海": "上海",
        "北京": "北京",
        "广州": "广东",
        "深圳": "广东",
        "杭州": "浙江",
        "武汉": "湖北",
        "长沙": "湖南",
        "成都": "四川",
        "石家庄": "河北",
        "太原": "山西",
        "郑州": "河南",
        "天津": "天津",
        "南京": "江苏",
        "合肥": "安徽",
        "重庆": "重庆",
        "长春": "吉林",
        "大连": "辽宁",
        "苏州": "江苏",
        "沈阳": "辽宁",
        "哈尔滨": "黑龙江",
        "西安": "陕西",
        "福州": "福建",
        "南昌": "江西",
        "呼和浩特": "内蒙古",
        "济南": "山东",
        "青岛": "山东",
        "南宁": "广西",
        "厦门": "福建",
        "贵阳": "贵州",
        "昆明": "云南",
        "宁波": "浙江",
        "保定": "河北",
        "乌鲁木齐": "新疆",
        "兰州": "甘肃",
        "无锡": "江苏",
        "唐山": "河北",
        "佛山": "广东",
        "银川": "宁夏",
        "廊坊": "河北",
        "东莞": "广东",
        "烟台": "山东",
        "嘉兴": "浙江",
        "常州": "江苏",
        "西宁": "青海",
        "柳州": "广西",
        "桂林": "广西",
        "温州": "浙江",
        "邯郸": "河北",
        "海口": "海南",
        "芜湖": "安徽",
        "湖州": "浙江",
        "宁德": "福建",
        "金华": "浙江",
        "扬州": "江苏",
        "沧州": "河北",
        "赣州": "江西",
        "鄂尔多斯": "内蒙古",
        "南通": "江苏",
        "泉州": "福建",
        "包头": "内蒙古",
        "绍兴": "浙江",
        "上饶": "江西",
        "临汾": "山西",
        "中山": "广东",
        "洛阳": "河南",
        "泰州": "江苏",
        "秦皇岛": "河北",
        "龙岩": "福建",
        "邢台": "河北",
        "长治": "山西",
        "吉林市": "吉林",
        "晋中": "山西",
        "三亚": "海南",
        "珠海": "广东",
        "盐城": "江苏",
        "淮安": "江苏",
        "拉萨": "西藏",
        "自贡": "四川",
        "阜阳": "安徽",
        "徐州": "江苏",
        "铁岭": "辽宁",
        "潍坊": "山东",
        "香港": "香港",
        "昆山": "江苏",
        "曲靖": "云南",
        "新乡": "河南",
        "大同": "山西",
        "惠州": "广东",
        "九江": "江西",
        "张家口": "河北",
        "连云港": "江苏",
        "抚顺": "辽宁",
        "德州": "山东",
        "平顶山": "河南",
        "常熟": "江苏",
        "宿迁": "江苏",
        "济宁": "山东",
        "赤峰": "内蒙古",
        "株洲": "湖南",
        "衡水": "河北",
        "江门": "广东",
        "襄阳": "湖北",
        "运城": "山西",
        "宜昌": "湖北",
        "钦州": "广西",
        "葫芦岛": "辽宁",
        "蚌埠": "安徽",
        "营口": "辽宁",
        "丽水": "浙江",
        "东营": "山东",
        "承德": "河北",
        "南阳": "河南",
        "义乌": "浙江",
        "伊春": "黑龙江",
        "汕头": "广东",
        "日照": "山东",
        "大庆": "黑龙江",
        "衢州": "浙江",
        "台州": "浙江",
        "马鞍山": "安徽",
        "佳木斯": "黑龙江",
        "吕梁": "山西",
        "澳门": "澳门",
        "荆州": "湖北",
        "聊城": "山东",
        "岳阳": "湖南",
        "淄博": "山东",
        "商丘": "河南",
        "信阳": "河南",
        "广安": "四川",
        "景德镇": "江西",
        "喀什": "新疆",
        "镇江": "江苏",
        "澄迈": "海南",
        "清远": "广东",
        "安庆": "安徽",
        "咸阳": "陕西",
        "浙江省": "浙江",
        "伊犁": "新疆",
        "湛江": "广东",
        "毕节": "贵州",
        "湘潭": "湖南",
        "黔南": "贵州",
        "宣城": "安徽",
        "新余": "江西",
        "延安": "陕西",
        "肇庆": "广东",
        "巴彦淖尔": "内蒙古",
        "萍乡": "江西",
        "阿勒泰": "新疆",
        "朔州": "山西",
        "湘西": "湖南",
        "延边": "吉林",
        "七台河": "黑龙江",
        "丹东": "辽宁",
        "威海": "山东",
        "乌海": "内蒙古",
        "南充": "四川",
        "漯河": "河南",
        "齐齐哈尔": "黑龙江",
        "焦作": "河南",
        "宜宾": "四川",
        "铜仁": "贵州",
        "锡林郭勒盟": "内蒙古",
        "泸州": "四川",
        "宝鸡": "陕西",
        "鞍山": "辽宁",
        "松原": "吉林",
        "宿州": "安徽",
        "贵港": "广西",
        "日喀则": "西藏",
        "白城": "吉林",
        "台湾": "台湾",
        "安顺": "贵州",
        "太仓": "江苏",
        "临沂": "山东",
        "玉溪": "云南",
        "忻州": "山西",
        "哈密": "新疆",
        "遵义": "贵州",
        "眉山": "四川",
        "莆田": "福建",
        "锦州": "辽宁",
        "荆门": "湖北",
        "晋城": "山西",
        "乐山": "四川",
        "许昌": "河南",
        "黔西南": "贵州",
        "开封": "河南",
        "渭南": "陕西",
        "梅州": "广东",
        "吉林": "吉林",
        "天水": "甘肃",
        "河源": "广东",
        "益阳": "湖南",
        "广东省": "广东",
        "博尔塔拉": "新疆",
        "海宁": "浙江",
        "吐鲁番": "新疆",
        "亳州": "安徽",
        "郴州": "湖南",
        "周口": "河南",
        "菏泽": "山东",
        "鹤岗": "黑龙江",
        "酒泉": "甘肃",
        "金昌": "甘肃",
        "商洛": "陕西",
        "榆林": "陕西",
        "德阳": "四川",
        "张家港": "江苏",
        "舟山": "浙江",
        "文山": "云南",
        "来宾": "广西",
        "阿里": "西藏",
        "濮阳": "河南",
        "江西省": "江西",
        "辽阳": "辽宁",
        "六盘水": "贵州",
        "湖北省": "湖北",
        "安阳": "河南",
        "楚雄州": "云南",
        "黄石": "湖北",
        "韶关": "广东",
        "白银": "甘肃",
        "常德": "湖南",
        "庆阳": "甘肃",
        "驻马店": "河南",
        "阳江": "广东",
        "安康": "陕西",
        "淮南": "安徽",
        "吴忠": "宁夏",
        "黔东南": "贵州",
        "江苏省": "江苏",
        "宜春": "江西",
        "本溪": "辽宁",
        "泰安": "山东",
        "达州": "四川",
        "玉林": "广西",
        "塔城": "新疆",
        "吉安": "江西",
        "张掖": "甘肃",
        "潜江市": "湖北",
        "绥化": "黑龙江",
        "滁州": "安徽",
        "澄迈县": "海南",
        "辽源": "吉林",
        "福建": "福建",
        "武威": "甘肃",
        "衡阳": "湖南",
        "平凉": "甘肃",
        "孝感": "湖北",
        "陇南": "甘肃",
        "随州": "湖北",
        "海东": "青海",
        "通化": "吉林",
        "内江": "四川",
        "北海": "广西",
        "广元": "四川",
        "云浮": "广东",
        "嘉峪关": "甘肃",
        "大理": "云南",
        "绵阳": "四川",
        "红河州": "云南",
        "西双版纳": "云南",
        "百色": "广西",
        "池州": "安徽",
        "凉山": "四川",
        "鄂州": "湖北"
        # 这里可以继续添加其他城市和省份的映射关系
    }
    df['province'] = df['city'].map(city_to_province)
    # 只保留对应省份的数据
    df = filter_provinces(df)

    # 清洗薪资范围
    # 删除薪资范围为空的行
    df.drop(df[df['薪资范围'].isnull().values].index, inplace=True)
    # 删除按天计数的行
    df = df[~df['薪资范围'].str.contains('天')]
    # 重新设置索引
    df.reset_index(drop=True, inplace=True)
    min_salary = []
    max_salary = []
    additional = []

    # 处理薪资范围
    for i in df['薪资范围']:
        if '天' in i:
            continue
        if '及以下' in i:  # 处理'及以下'情况
            if '万' in i:
                min_salary.append(float(i.split('万')[0]) * 10000)
                max_salary.append(float(i.split('万')[0]) * 10000)  # 取相同值
                additional.append(np.nan)  # 为保持一致性添加 NaN
            elif '千' in i:
                min_salary.append(float(i.split('千')[0]) * 1000)
                max_salary.append(float(i.split('千')[0]) * 1000)  # 取相同值
                additional.append(np.nan)  # 为保持一致性添加 NaN
            continue

        # 其他情况的处理逻辑
        if i.count('万') == 1 and i.count('千') == 1:
            min_salary.append(float(i.split('千')[0]) * 1000)
            max_salary.append(float(i.split('-')[1].split('万')[0]) * 10000)
        elif i.count('万/年') == 1:
            min_salary.append(round((float(i.split('-')[0]) * 10000) / 12, 2))
            max_salary.append(round((float(i.split('-')[0]) * 10000) / 12, 2))
        elif '千及以下' in i:
            min_salary.append(int(i[0]) * 1000)
            max_salary.append(int(i[0]) * 1000)
        elif i.count('千') == 1 and '万' not in i:
            min_salary.append(float(i.split('-')[0]) * 1000)
            max_salary.append(float(i.split('-')[1].split('千')[0]) * 1000)
        elif i.count('千') == 1 and '天' in i:
            min_salary.append(float(i.split('千')[0]) * 365)
            max_salary.append(float(i.split('千')[0]) * 365)
        elif i.count('万') == 1 and '千' not in i:
            min_salary.append(float(i.split('-')[0]) * 10000)
            max_salary.append(float(i.split('-')[1].split('万')[0]) * 10000)
        else:
            min_salary.append(int(i.split('元')[0]) * 30)
            max_salary.append(int(i.split('元')[0]) * 30)

        # 薪资范围中，如果含有“薪”字，说明年薪有额外工资
        if '薪' in i:
            additional.append(int(i.split('·')[1].replace('薪', '')))
        else:
            additional.append(np.nan)

    # 更新数据框
    # 此处需要确保三个列表的长度一致
    if len(min_salary) == len(max_salary) == len(additional) == len(df):
        df['min_salary'] = min_salary
        df['max_salary'] = max_salary
        df['additional_salary'] = additional
    else:
        print(
            f"长度不一致: min_salary={len(min_salary)}, max_salary={len(max_salary)}, additional={len(additional)}, df={len(df)}")

    # 整合数据
    df['source'] = '前程无忧'
    df['salary'] = df['薪资范围']
    df = df[[
        'job_id', 'source', 'position', 'company', 'province', 'city',
        'min_salary', 'max_salary', 'additional_salary', 'salary',
        'experience', 'education', 'responsibility', 'scale',
        'position_link', 'job_create_time', 'job_update_time']]

    # 清洗经验
    mapping = {
        '无需经验': '经验不限',
        '应届毕业生': '在校/应届',
        '无经验': '经验不限',
        '不限': '经验不限',
        '应届': '在校/应届',
        '一年以下': '1年以上',
        '1年以下': '1年以上',
        '1年以内': '1年以上',
        '1-2年': '1年以上',
        '1-5年': '1年以上',
        '1-4年': '1年以上',
        '1年': '1年以上',
        '2年': '2年以上',
        '2-4年': '2年以上',
        '2-3年': '2年以上',
        '1-3年': '1年以上',
        '3-5年': '1年以上',
        '3-4年': '3年以上',
        '3-7年': '3年以上',
        '3-10年': '3年以上',
        '3-6年': '3年以上',
        '4年及以上': '3年以上',
        '5-10年': '5年以上',
        '5-7年': '5年以上',
        '6年及以上': '5年以上',
        '7年及以上': '5年以上',
        '8年及以上': '5年以上',
        '8-9年': '10年以上',
        '9年及以上': '10年以上',
        '10年及以上': '10年以上'
    }
    df['experience'] = df['experience'].replace(mapping)
    df['experience'].value_counts()

    # 清洗公司规模
    df['scale'].value_counts()
    mapping = {
        '少于50人': '0-20人',
        '50-150人': '20-99人',
        '150-500人': '100-499人',
        '500-1000人': '500-999人',
        '1000-5000人': '1000-9999人',
        '5000-10000人': '1000-9999人',
        '10000人以上': '10000人以上'
    }
    df['scale'] = df['scale'].replace(mapping)
    df['scale'].value_counts()

    # 重新合并保存数据
    df = df[
        ['job_id', 'source', 'position', 'company', 'province', 'city', 'min_salary', 'max_salary', 'additional_salary',
         'salary', 'experience', 'education', 'responsibility', 'scale', 'position_link', 'job_create_time',
         'job_update_time']]
    df.to_csv(path, index=False)

# 合并数据
def Marge_Data(Path):
    file_list = read_file(Path)
    print(file_list)
    # 创建一个空的数据框，用于存储合并后的数据
    merged_df = pd.DataFrame()
    # 循环读取并合并每个CSV文件
    for excel_file in file_list:
        if excel_file!= 'Merged_Data.csv':
            # 构建完整的文件路径
            file_path = os.path.join(Path, excel_file)
            # 读取CSV文件
            df = pd.read_csv(file_path)
            # 将当前文件的数据合并到总的数据框中
            merged_df = pd.concat([merged_df, df], ignore_index=True)
    # 将合并后的数据框保存到新的CSV文件中
    merged_df.to_csv(f'{file_title}temp/Merged_Data.csv', index=False)

# 根据关键字对职位进行分类
def classify_position(row):
    # 定义职位关键词与职位分类的映射关系
    position_map = {
        '数据分析工程师': ['分析', '建模', '数据湖'],
        '大数据工程师': ['数仓', 'DB', '支持', '大数据工程师', '开发工程师'],
        '算法工程师': ['算法', 'AI', 'ai', '机器学习'],
        '大数据架构师': ['架构'],
        '开发工程师': ['开发', '研发', 'Java', 'java', '预处理', 'BI', 'ETL', 'bi', '可视化'],
        '运维工程师': ['运维', 'Hadoop'],
        '运营工程师': ['运营', '销售', '顾问', '管理', '产品经理', '项目经理', '售前', '售后', '经理', '负责人', '组长',
                       '主管', '总监'],
        '数据采集工程师': ['采集', '清洗', '爬虫'],
        '数据标注师': ['标注'],
        '大数据治理工程师': ['治理', '规划', '安全'],
        '数据挖掘工程师': ['挖掘'],
        '大数据讲师': ['讲师', '教师', '老师']
    }

    # 遍历映射字典并检查职位名称是否包含关键词
    for position_type, keywords in position_map.items():
        if any(keyword in row['position'] for keyword in keywords):
            return position_type

    return '其它'


# 清洗合并后的数据
def wash_Merged_Data():
    df = pd.read_csv(f'{file_title}temp/Merged_Data.csv')
    df['classify'] = None

    # 使用分类函数创建 'classify' 列
    df['classify'] = df.apply(classify_position, axis=1)

    # 清洗教育
    df['education'] = df['education'].replace('中技/中专', '中专', regex=True)
    df['education'] = df['education'].replace('大专', '专科', regex=True)
    # 将空白字符串和其他缺失值替换为NaN
    df.replace('', pd.NA, inplace=True)
    df.replace('其他缺失值', pd.NA, inplace=True)
    # 将"education"字段中的NaN填充为"学历不限"
    df['education'].fillna('学历不限', inplace=True)

    # 只保留position字段或responsibility字段包含 “数据” 的行
    df = df[((df['position'].str.contains('数据')) | (df['responsibility'].str.contains('数据')))]

    # 写数据
    df.to_sql('emp_data', con=engine, if_exists='append', index=False)
    # 关闭数据库连接
    engine.dispose()

# 分析数据，写入数据库
# 薪水前十
def avg_salary_Top10():
    # 读取数据
    df_db = pd.read_sql_table('emp_data', con=engine)
    # 薪水前十
    # 计算均值
    df_db['avg_salary'] = df_db.apply(lambda row: (row['max_salary'] + row['min_salary']) / 2, axis=1)
    df_p = df_db.groupby(['classify']).agg({'avg_salary': 'mean'})[:10].reset_index()
    df_p['position'] = df_p['classify']

    current_time = datetime.now()
    # # 将当前时间分配给DataFrame中的特定列
    df_p[['create_time', 'update_time']] = current_time
    # df_p['create_time'] = df_db['create_time']
    df_p['id'] = None
    df_p = df_p[['id', 'position', 'avg_salary', 'create_time', 'update_time']]
    # 取整操作
    df_p['avg_salary'] = [int(i) for i in df_p['avg_salary']]
    # 更新数据库中的数据
    df_p.to_sql('analysis_salary', con=engine, if_exists='append', index=False)

    # 关闭数据库连接
    engine.dispose()


#  不同学历的薪水与需求量
def analysis_education():
    #  不同学历的薪水与需求量
    df = pd.read_sql_table('emp_data', con=engine)
    df['avg_salary'] = df.apply(lambda row: (row['max_salary'] + row['min_salary']) / 2, axis=1)

    df_x = df.groupby('education').agg({'avg_salary': 'mean', 'source': 'count'})
    order = ['学历不限', '中专', '高中', '专科', '本科', '硕士', '博士']
    df_x = grouped_data = df_x.reindex(order)

    df_x = df_x.reset_index(drop=False).rename(columns={'average_salary': 'avg_salary', 'source': 'position_num'})
    df_x['create_time'] = df_x['update_time'] = df_x['id'] = np.nan

    # 将当前时间分配给DataFrame中的特定列
    current_time = datetime.now()
    df_x[['create_time', 'update_time']] = current_time

    df_x = df_x[['id', 'education', 'position_num', 'avg_salary', 'create_time', 'update_time']]

    # 写数据
    df_x.to_sql('analysis_education', con=engine, if_exists='append', index=False)
    # 关闭数据库连接
    engine.dispose()



# 招聘企业规模环形分布图
def analysis_scale():
    # 读取已有的数据
    df = pd.read_sql_table('emp_data', con=engine)
    df['avg_salary'] = df.apply(lambda row: (row['max_salary'] + row['min_salary']) / 2, axis=1)

    # 使用 groupby 和 agg 计算所需的统计数据
    grouped_data = df.groupby('scale').agg({'position': 'count', 'avg_salary': 'mean'})
    order = ['0-20人', '20-99人', '100-499人', '500-999人', '1000-9999人', '10000人以上']

    grouped_data['position_num'] = grouped_data['position']
    grouped_data = grouped_data.reindex(order)
    grouped_data = grouped_data.reset_index(drop=False)
    grouped_data['id'] = np.nan

    # 将当前时间分配给 DataFrame 中的特定列
    current_time = datetime.now()
    grouped_data[['create_time', 'update_time']] = current_time

    # 计算 scale_num
    grouped_data['scale_num'] = df.groupby('scale')['company'].nunique().reindex(order).values

    # 处理 avg_salary，使用 fillna() 和 apply() 方法
    grouped_data['avg_salary'] = grouped_data['avg_salary'].fillna(0).apply(lambda x: int(x))

    # 只保留需要的列
    grouped_data = grouped_data[
        ['scale', 'scale_num', 'id', 'position_num', 'avg_salary', 'create_time', 'update_time']]

    # 写数据
    grouped_data.to_sql('analysis_scale', con=engine, if_exists='append', index=False)

    # 关闭数据库连接
    engine.dispose()


# 地图数据
def Map_Data():
    df = pd.read_sql_table('emp_data', con=engine)

    # 数据处理，确保省份名字一致
    province_mapping = {
        "广西": "广西壮族自治区",
        "宁夏": "宁夏回族自治区",
        "内蒙古": "内蒙古自治区",
        "北京": "北京市",
        "天津": "天津市",
        "上海": "上海市",
        "香港": "香港特别行政区",
        "澳门": "澳门特别行政区",
        "云南": "云南省",
        "吉林": "吉林省",
        "四川": "四川省",
        "台湾": "台湾省",
        "安徽": "安徽省",
        "山东": "山东省",
        "山西": "山西省",
        "广东": "广东省",
        "新疆": "新疆维吾尔自治区",
        "江苏": "江苏省",
        "江西": "江西省",
        "河北": "河北省",
        "河南": "河南省",
        "浙江": "浙江省",
        "海南": "海南省",
        "湖北": "湖北省",
        "湖南": "湖南省",
        "甘肃": "甘肃省",
        "福建": "福建省",
        "西藏": "西藏自治区",
        "贵州": "贵州省",
        "辽宁": "辽宁省",
        "重庆": "重庆市",
        "陕西": "陕西省",
        "青海": "青海省",
        "黑龙江": "黑龙江省"
    }

    df['province'] = df['province'].map(province_mapping).fillna("未知省份")

    # 统计各个地区的数据
    result = df.groupby('province').agg({'classify': 'count'}).reset_index()

    # 统计每个地区的前五岗位
    result_top = df.groupby(['province', 'classify'])['source'].count().reset_index()
    result_top = result_top.sort_values(['province', 'source'], ascending=[True, False])

    province_positions = {}
    for province, group in result_top.groupby('province'):
        top_positions = group.head(5).set_index('classify').to_dict()['source']
        province_positions[province] = top_positions

    top_p = []
    for i in province_positions:
        top_p.append(province_positions[i])

    result['top_position'] = top_p

    # 添加时间戳和id
    current_time = datetime.now()
    result[['create_time', 'update_time']] = current_time
    result['id'] = np.nan

    # 重命名列
    result = result.rename(columns={'classify': 'total_position'})
    result['top_position'] = result['top_position'].astype('str')

    # 确保所有省份都在结果中，如果没有数据，total_position添为0，top_position为空
    all_provinces = list(province_mapping.values())
    missing_provinces = set(all_provinces) - set(result['province'])
    missing_data = pd.DataFrame(
        {'province': list(missing_provinces), 'total_position': 0, 'top_position': '', 'create_time': current_time,
         'update_time': current_time})
    result = pd.concat([result, missing_data]).sort_values('province').reset_index(drop=True)

    # 过滤掉未知省份的数据
    result = result[result['province'] != '未知省份']

    # # 写数据
    result.to_sql('analysis_province', con=engine, if_exists='append', index=False)

    # 关闭数据库连接
    engine.dispose()


# 根据job_id去重
def Data_deduplication():
    # 读取数据到DataFrame
    df = pd.read_sql('SELECT * FROM emp_data', engine)

    # 查找重复的job_id并保留第一条记录
    df_unique = df.drop_duplicates(subset='job_id', keep='first')

    # 删除原表的数据
    with engine.connect() as connection:
        connection.execute("DELETE FROM emp_data")

    # 将去重后的数据写回数据库
    df_unique.to_sql('emp_data', engine, if_exists='append', index=False)

    # 关闭数据库连接
    engine.dispose()


# 读取文件列表
def read_file(Path):
    folder_path = Path
    file_list = os.listdir(folder_path)
    return file_list


# 定义一个函数来删除目录中的所有文件
def clear_directory(directory):
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        try:
            if os.path.isfile(file_path):  # 检查是否是文件
                os.remove(file_path)
            elif os.path.isdir(file_path):  # 检查是否是目录
                shutil.rmtree(file_path)  # 删除子目录及其内容
        except Exception as e:
            print(f"Error deleting {file_path}: {e}")


if "__main__" == __name__:
    try:
        # 获取从Java传过来的参数
        keyword = sys.argv[1]  # 获取第一个参数
        file_title = sys.argv[2]  # 获取第二个参数
        # file_title = 'E:/employment_data_analysis/analysis-parent/src/main/resources/python/crawlers_analytics/'
        # keyword = "大数据架构师"  # 获取第一个参数
        print(f'文件位置: {file_title}')
        print(f'关键词：{keyword}')

        # 有传入关键词，才执行脚本
        if keyword:
            get_data(keyword)

            # 读取文件列表
            Path = f'{file_title}script_data/'
            file_list = read_file(Path)

            # 解析数据，初次清洗
            analysis_json(file_list)

            # 初次清洗的数据
            New_Data = f'{file_title}temp/'
            # 合并数据
            Marge_Data(New_Data)

            # 清洗合并后的数据
            wash_Merged_Data()

            # 根据id去重
            Data_deduplication()

            # 插入分析数据
            # 插入收入前十
            avg_salary_Top10()

            # 不同学历的薪水与需求量
            analysis_education()

            # 招聘企业规模环形分布图
            analysis_scale()

            # 地图数据
            Map_Data()

            # 清空 after_wash_data 和 temp 目录
            clear_directory(file_title + 'script_data')
            clear_directory(file_title + 'temp')

    except Exception as e:
        print(f"程序执行时出错: {e}")
